﻿#include "FITKAcousticsVTKGraphObject3DPost.h"
#include "FITKAcousticsVTKGraphActor.h"

// VTK
#include <vtkProperty.h>
#include <vtkPoints.h>
#include <vtkDataSet.h>
#include <vtkMapper.h>
#include <vtkCellData.h>
#include <vtkLookupTable.h>
#include <vtkDoubleArray.h>

// App
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"

// Graph and filter
#include "FITKAcousticsVTKCommons.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActor.h"

namespace Exchange
{
    FITKAcousticsVTKGraphObject3DPost::FITKAcousticsVTKGraphObject3DPost(Core::FITKAbstractDataObject* dataObj)
        : FITKAcousticsVTKGraphObject3D(dataObj)
    {
        // Nothing to do here.
    }

    void FITKAcousticsVTKGraphObject3DPost::setPostData(QString arrayName, QHash<QString, float> & data)
    {
        // Override in sub-class.
        Q_UNUSED(arrayName);
        Q_UNUSED(data);
    }

    void FITKAcousticsVTKGraphObject3DPost::updateByDataColor()
    {
        // Override in sub-class.
    }

    void FITKAcousticsVTKGraphObject3DPost::updateByPostCellData(QString arrayName, double rangeMin, double rangeMax)
    {
        // Override in sub-class.
        Q_UNUSED(arrayName);
        Q_UNUSED(rangeMin);
        Q_UNUSED(rangeMax);
    }

    void FITKAcousticsVTKGraphObject3DPost::updateByPostNullData()
    {
        // Override in sub-class.
    }

    void FITKAcousticsVTKGraphObject3DPost::setEnableLogScale(bool isOn)
    {
        // Override in sub-class.
        Q_UNUSED(isOn);
    }

    void FITKAcousticsVTKGraphObject3DPost::initLookUptable(vtkScalarsToColors* lut)
    {
        vtkLookupTable* lookupTable = vtkLookupTable::SafeDownCast(lut);
        if (!lookupTable)
        {
            return;
        }

        // Update the out of range color.
        double colorAbove3[3]{ 0., 0., 0. };
        double colorBelow3[3]{ 0., 0., 0. };
        FITKAcousticsVTKCommons::QColorToDouble3(FITKAcousticsVTKCommons::s_postAboveColor, colorAbove3);
        FITKAcousticsVTKCommons::QColorToDouble3(FITKAcousticsVTKCommons::s_postBelowColor, colorBelow3);
        lookupTable->SetAboveRangeColor(colorAbove3);
        lookupTable->SetBelowRangeColor(colorBelow3);

        // Update the HSV range.( Blue to red )
        lookupTable->SetHueRange(0.666667, 0);
        lookupTable->SetSaturationRange(1, 1);
        lookupTable->SetValueRange(1, 1);
    }

    vtkLookupTable* FITKAcousticsVTKGraphObject3DPost::getActorLut(vtkActor* actor)
    {
        if (!actor)
        {
            return nullptr;
        }

        // Get the mapper.
        vtkMapper* mapper = actor->GetMapper();
        if (!mapper)
        {
            return nullptr;
        }

        // Get or create the look up table.
        vtkLookupTable* lut = vtkLookupTable::SafeDownCast(mapper->GetLookupTable());
        if (!lut)
        {
            vtkSmartPointer<vtkLookupTable> newLut = vtkSmartPointer<vtkLookupTable>::New();
            mapper->SetLookupTable(newLut);
            lut = newLut;
        }

        return lut;
    }

    void FITKAcousticsVTKGraphObject3DPost::setValueToCellData(vtkDataSet* dataSet, QString arrayName, double value)
    {
        if (!dataSet || arrayName.isEmpty())
        {
            return;
        }

        vtkCellData* cellData = dataSet->GetCellData();
        if (!cellData)
        {
            return;
        }

        // Get or create the data array.
        vtkDoubleArray* dbArray = vtkDoubleArray::SafeDownCast(cellData->GetArray(arrayName.toUtf8().data()));
        if (dbArray)
        {
            dbArray->Reset();
            dbArray->SetNumberOfComponents(1);
            dbArray->SetNumberOfValues(0);
        }
        else
        {
            vtkSmartPointer<vtkDoubleArray> newArr = vtkSmartPointer<vtkDoubleArray>::New();
            newArr->SetName(arrayName.toUtf8().data());
            cellData->AddArray(newArr);
            dbArray = newArr;
        }

        // Fill values.
        dbArray->SetNumberOfValues(dataSet->GetNumberOfCells());
        dbArray->FillComponent(0, value);
    }
}   // namespace Exchange